package com.glodon.springbootmutidatasourse.aop;

import com.glodon.springbootmutidatasourse.annotation.DataSource;
import com.glodon.springbootmutidatasourse.datasource.DynamicDataSourceContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.lang.reflect.Method;

/**
 * @author zhaoxin
 * @version 1.0
 * @description: DataSource切面类
 * @date 2021/11/12 10:39
 */
@Aspect
@Component
@Order(-1)// 保证该AOP在@Transactional之前执行
@Slf4j
public class DynamicDataSourceAspect {
    @Pointcut("@annotation(com.glodon.springbootmutidatasourse.annotation.DataSource)"
            +"|| @within(com.glodon.springbootmutidatasourse.annotation.DataSource)")
    public void dsPointCut(){

    }
    @Around("dsPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        MethodSignature signature = (MethodSignature) point.getSignature();

        Class targetClass = point.getTarget().getClass();
        Method method = signature.getMethod();
        //获取要切换的数据源
        DataSource targetDataSource = (DataSource)targetClass.getAnnotation(DataSource.class);
        DataSource methodDataSource = method.getAnnotation(DataSource.class);
        if(targetDataSource != null || methodDataSource != null){
            String value;
            if(methodDataSource != null){
                value = methodDataSource.name().name();
            }else {
                value = targetDataSource.name().name();
            }
            DynamicDataSourceContextHolder.setDataSourceType(value);
            log.info("DB切换成功，切换至{}",value);
        }

        try {
            return point.proceed();
        } finally {
            log.info("清除DB切换");
            // 销毁数据源 在执行方法之后
            DynamicDataSourceContextHolder.removeDataSourceType();
        }



    }
}
